#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <wiringPi.h>

#include "msg_queue.h"
#include "control.h"
#include "global.h"
#include "voice_interface.h"
#include "socket_interface.h"
#include "smoke_interface.h"
#include "receive_interface.h"

/**
 * 智能家居系统主函数
 * 
 * 功能概述：
 * 1. 初始化硬件和系统资源
 * 2. 构建控制模块链表
 * 3. 初始化各个控制模块
 * 4. 创建线程处理各个控制模块的数据监听
 * 5. 等待所有线程执行完毕
 * 6. 释放系统资源
 * 
 * 系统架构：
 * - 使用链表管理各种控制接口(语音、Socket、烟雾、接收等)
 * - 使用消息队列实现模块间通信
 * - 使用多线程并发处理不同类型的控制信号
 */
int main(int argc, char *argv[])
{
    pthread_t thread_id;    //线程ID变量（虽然声明了但没有使用）
    struct control *control_pthread = NULL;//控制线程指针（虽声但未）
    struct control *pointer = NULL;//遍历控制链表的指针

    //初始化wiringPi库，用于GPIO控制
    if (wiringPiSetup() == -1)
    {
        printf("wiringPiSetup failed\n");
        return -1;
    }

    //声明并初始化全局控制信息结构体
    ctrl_info_t *ctrl_info = NULL;

    //为全局控制信息分配内存
    ctrl_info = (ctrl_info_t *)malloc(sizeof(ctrl_info_t));
    ctrl_info->ctrl_phead = NULL;//初始化控制链表头指针为空
    ctrl_info->mqd = -1;    //初始化消息队列为无效值

    int node_num = 0;//记录控制模块节点数量

    //创建消息队列用于模块间通信
    ctrl_info->mqd = msg_queue_create();

    //检查消息队列用于模块间通信
    if(ctrl_info->mqd == -1){
        perror("msg_queue_create failed");
        return -1;
    }

    //依次添加各种控制接口到控制链表中
    //使用头插法构建控制模块链表
    ctrl_info->ctrl_phead = add_voice_to_ctrl_list(ctrl_info->ctrl_phead);
    ctrl_info->ctrl_phead = add_tcpsocket_to_ctrl_list(ctrl_info->ctrl_phead);
    ctrl_info->ctrl_phead = add_smoke_to_ctrl_list(ctrl_info->ctrl_phead);
    ctrl_info->ctrl_phead = add_receive_to_ctrl_list(ctrl_info->ctrl_phead);

    //遍历控制链表，初始化每个控制模块
    pointer = ctrl_info->ctrl_phead;
    while(NULL != pointer){
        //检查当前控制模块是否有初始化函数
        if(NULL != pointer->init){
            pointer->init();//调用初始化函数
        }
        pointer = pointer->next;//移动到下一个控制模块
        node_num++;//统计控制模块数量
    }

    //为线程ID数组分配内存
    pthread_t *tid = malloc(sizeof(pthread_t) * node_num);

    //重新遍历控制链表，为每个有监听函数的模块创建线程
    pointer = ctrl_info->ctrl_phead;
    for(int i = 0; i < node_num; i++){
        //检查当前控制模块是否有数据监听函数（get函数）
        if(NULL != pointer->get)
        {
            //创建线程处理该控制模块的数据监听
            pthread_create(&tid[i], NULL, (void*)pointer->get, (void*)ctrl_info);
        }
        pointer = pointer->next;    //移动到下一个控制模块
    }

    //等待所有创建的线程执行完毕
    for(int i = 0; i < node_num; i++){
        pthread_join(tid[i], NULL); //阻塞等待第i个线程结束
    }

    // 修正：重新获取链表头，准备调用各个模块的结束函数
    pointer = ctrl_info->ctrl_phead;
    for(int i = 0; i < node_num; i++){
        //检查当前控制模块释放是否有结束函数
        if(NULL != pointer->final){
            pointer->final();   //调用结束函数，释放资源
        }
        pointer = pointer->next;    //移动到下一个控制模块
    }

    //释放消息的队列资源
    msg_queue_final(ctrl_info->mqd);

    //释放全局控制信息内存
    if(ctrl_info != NULL)
    {
        free(ctrl_info);
    }

    if(tid != NULL)//释放线程ID数组内存
    {
        free(tid);
    }

    return 0;//程序正常退出
}